<template>
    <div class="chart-setting-config">
      <div class="title">
        <div class="title-left">
          <i class="el-icon-arrow-left" @click="close"></i>
          <input :style="formNameStyle" v-model="formData.name" v-on:input="handleNameChange"/>
        </div>
        <div class="title-right">
          <el-button @click="handleSave">保存</el-button>
        </div>
      </div>
      <div class="chart-config">
        <div class="chart-left">
          <div class="data-block">
            <div class="block-head">
              <span class="block-title">
                数据源
              </span>
              <span class="block-right" @click="formListVisible = true">
                更改数据源
              </span>
            </div>
            <div class="block-data-source">
              <i class="menu-icon el-icon-s-order"></i>
              <span>{{worksheetName}}</span>
            </div>
          </div>
          <div class="fields-block">
            <div class="block-head">
              <span class="block-title">
                字段
              </span>
            </div>
            <div class="block-content">
              <vuedraggable :list="fieldList" :sort="false" :clone="onFieldClone" :group="{ name: 'people', pull: 'clone', put: false }" :move="onFieldMove" @unchoose="chooseFlag = false">
                <div class="item" v-for="item in fieldList" :key="item.name">
                  <i class="menu-icon el-icon-help"></i>
                  <span>{{item.alia}}</span>
                </div>
              </vuedraggable>
            </div>
          </div>
        </div>
        <div class="chart-middle">
          <div class="chart-axis" v-show="formData.chartType !== 'numberGraphic'">
            <div class="axis-head">维度</div>
            <div class="drag-target">
              <span class="drag-tip" v-show="formData.xAxis.length === 0">拖动左侧字段到此处来添加维度</span>
              <vuedraggable v-model="formData.xAxis" class="drag-axis" id="xAxis" group="people">
                <chart-x-axis v-for="item in formData.xAxis"
                  :key="item.uuid"
                  :axis="item"
                  @deleteDrag="deleteDrag"
                  @change="dragChange"
                />
              </vuedraggable>
            </div>
          </div>
          <div class="chart-axis">
            <div class="axis-head">指标</div>
            <div class="drag-target">
              <span class="drag-tip" v-show="formData.yAxis.length === 0">拖动左侧字段到此处来添加指标</span>
              <vuedraggable v-model="formData.yAxis" class="drag-axis" id="yAxis" group="people" :move="onFieldMove" @unchoose="chooseFlag = false">
                <chart-y-axis v-for="item in formData.yAxis"
                  :key="item.uuid"
                  :axis="item"
                  @deleteDrag="deleteDrag"
                  @change="dragChange"
                />
              </vuedraggable>
            </div>
          </div>
          <div class="chart-axis">
            <div class="axis-head">过滤条件</div>
            <div class="drag-target" style="padding-right: 70px">
              <span class="drag-tip" v-show="formData.filters.length === 0">拖动左侧字段到此处来添加过滤条件</span>
              <vuedraggable v-model="formData.filters" class="drag-axis" id="filters" group="people" @add="onFieldAdd" :move="onFieldMove" @unchoose="chooseFlag = false">
                <chart-filter v-for="item in formData.filters"
                  :key="item.uuid"
                  :axis="item"
                  @deleteDrag="deleteDrag"
                  @change="dragChange"
                />
              </vuedraggable>
            </div>
            <div class="axis-split-type">
              <a-select v-model="spliceType" @change="handleSpliceChange" style="width: 60px">
                <a-select-option :value="0">
                  且
                </a-select-option>
                <a-select-option :value="1">
                  或
                </a-select-option>
              </a-select>
            </div>
          </div>
          <div class="chart-content">
            <cgs-echarts v-if="formData.chartType !== 'numberGraphic' && worksheetData.length > 0"
              :title="formData.chartTitle"
              :type="formData.chartType"
              :data="worksheetData"
              :x="formData.xAxis"
              :y="formData.yAxis"
              :colors="formData.colorConfig"
              :limits="formData.colorLimit"
            />
            <cgs-number-graphic v-if="formData.chartType === 'numberGraphic' && worksheetData.length > 0"
              :unit="formData.numberStyle.unit"
              :font-size="formData.numberStyle.fontSize"
              :font-color="formData.numberStyle.fontColor"
              :data="worksheetData"
              :y="formData.yAxis"
            />
          </div>
        </div>
        <div class="chart-right">
          <div class="config-block">
            <div class="block-head">图表类型</div>
            <div class="config-chart-type">
              <a-radio-group v-model="formData.chartType" size="large">
                <a-tooltip>
                  <template slot="title">
                    柱状图
                  </template>
                  <a-radio-button value="bar">
                    <a-icon type="bar-chart" />
                  </a-radio-button>
                </a-tooltip>
                <a-tooltip>
                  <template slot="title">
                    折线图
                  </template>
                  <a-radio-button value="line">
                    <a-icon type="line-chart" />
                  </a-radio-button>
                </a-tooltip>
                <a-tooltip>
                  <template slot="title">
                    饼图
                  </template>
                  <a-radio-button value="pie" :disabled="formData.yAxis.length > 1">
                    <a-icon type="pie-chart" />
                  </a-radio-button>
                </a-tooltip>
                <a-tooltip>
                  <template slot="title">
                    数值图
                  </template>
                  <a-radio-button value="numberGraphic" :disabled="formData.yAxis.length > 1">
                    <a-icon type="number" />
                  </a-radio-button>
                </a-tooltip>
              </a-radio-group>
            </div>
          </div>
          <a-divider />
          <template v-if="formData.chartType !== 'numberGraphic'">
            <div class="config-block">
              <div class="config-color">排序字段</div>
              <div class="config-sort">
                <a-select v-model="formData.sortField" @change="updateWorksheetData" allowClear style="width: 120px">
                    <a-select-option v-for="item in fieldList" :key="item.field">
                        {{item.alia}}
                    </a-select-option>
                </a-select>
                <a-switch checked-children="升序" un-checked-children="降序" v-model="formData.isAsc" @change="updateWorksheetData"/>
              </div>
            </div>
            <a-divider />
            <div class="config-block">
              <div class="config-color">图表配色</div>
              <a-button class="length-button" @click="colorConfigModalVisible = true">设置</a-button>
            </div>
            <a-divider />
            <div class="config-block">
              <div class="config-color">数据预警</div>
              <a-button class="length-button" @click="handleAddColorLimit">添加预警</a-button>
              
              <div class="color-limit-container">
                <color-limit
                  v-for="list in formData.colorLimit"
                  :key="list.uuid"
                  :limit='list'
                  :fields="formData.yAxis"
                  @deleteColorLimit='handleDeleteColorLimit'
                />
              </div>
            </div>
          </template>
          <template v-if="formData.chartType === 'numberGraphic'">
            <div class="config-block">
              <div class="config-font">
                <span>单位</span>
                <a-input v-model="formData.numberStyle.unit" style="width: 100px"/>
              </div>
            </div>
            <a-divider />
            <div class="config-block">
              <div class="config-font">
                <span>字体大小</span>
                <a-input-number v-model="formData.numberStyle.fontSize" :min="12"
                  :formatter="value => `${value}px`"
                  :parser="value => value.replace('px', '')"
                />
              </div>
            </div>
            <div class="config-block">
              <div class="config-font">
                <span>字体颜色</span>
                <input type="color" v-model="formData.numberStyle.fontColor"/>
              </div>
            </div>
          </template>
        </div>
      </div>

      <form-list-modal v-if="formListVisible" 
        :visible="formListVisible"
        :formId="formData.worksheetId"
        @close="formListVisible = false"
        @save="formListSave"
      />

      <filter-modal v-if="filterModalVisible"
        :field="oneFilterData.alia"
        :dataType="oneFilterData.dataType"
        :dateRange="oneFilterData.dateRange"
        :filterType="oneFilterData.filterType"
        :values="oneFilterData.values"
        :visible="filterModalVisible"
        @close="filterClose"
        @save="filterSave"
      />

      <color-config-modal v-if="colorConfigModalVisible"
        :yAxis="formData.yAxis"
        :colors="formData.colorConfig"
        :visible="colorConfigModalVisible"
        @close="colorConfigModalVisible = false"
        @save="colorConfigSave"
      />
    </div>
</template>

<script>
import chartXAxis from "./chartXAxis.vue"
import chartYAxis from "./chartYAxis.vue"
import chartFilter from "./chartFilter.vue"
import filterModal from "./modal/filterModal.vue"
import colorLimit from "./colorLimit.vue"
import vuedraggable from 'vuedraggable';
import cgsEcharts from "../../components/chart/cgsEcharts.vue";
import cgsNumberGraphic from "../../components/chart/cgsNumberGraphic.vue";
import FormListModal from "./modal/formListModal.vue"
import colorConfigModal from "./modal/colorConfigModal.vue"
import {DataType, FilterType, DateRange} from '../../../../filterConstant'
import {getFilterDataList, getWorksheetDetail} from "@/api/worksheet"
import {getStrPx} from "@/utils/utils"
export default {
  props: {
    visible: Boolean,
    config: Object,
    model: String,
    worksheetId: String
  },
  components: {
    cgsEcharts,
    chartXAxis,
    chartYAxis,
    chartFilter,
    filterModal,
    colorLimit,
    cgsNumberGraphic,
    FormListModal,
    colorConfigModal,
    vuedraggable
  },
  data() {
    return {
      type: "chart",
      fieldType: "",
      formNameStyle: "",
      formListVisible: false,
      filterModalVisible: false,
      colorConfigModalVisible: false,
      worksheetName: '',
      fieldList: [],
      worksheetData: [],
      chooseFlag: false,
      formData: {
        name: "未命名",
        worksheetId: '',
        sortField: null,
        xAxis: [],
        yAxis: [],
        filters: [],
        xAlia: null,
        numberStyle: {
          fontSize: 20,
          fontColor: 'black',
          unit: ''
        },
        isAsc: false,
        chartType: 'bar',
        colorConfig: [],
        colorLimit: [],
        id: this.createId(),
      },
      spliceType: 0,
      oneFilterData: {
        uuid: '',
        alia: '',
        filterType: '',
        values: [],
        dateRange: null,
        dataType: 0,
      }
    };
  },
  methods: {
    dragChange(uuid, type, data){
      let index = this.formData[type].findIndex(d => d.uuid === uuid)
      this.formData[type][index] = Object.assign(this.formData[type][index], data)
      if(type === 'filters') {
        this.updateWorksheetData()
      }
    },
    deleteDrag(uuid, type){
      this.formData[type] = this.formData[type].filter(d => d.uuid !== uuid)
      if(type === 'filters') {
        this.updateWorksheetData()
      }
    },
    onFieldClone(e){
      console.log(e);
      let newData = JSON.parse(JSON.stringify(e))
      return Object.assign(newData, {
        uuid: this.createId()
      })
    },
    onFieldMove(e){
      if(e.to?.id === 'xAxis' && this.formData.xAxis.length > 0){
        if(!this.chooseFlag){
          this.$message.warning('维度目前只能添加一个')
          this.chooseFlag = true
        }
        return false
      } 
    },
    onFieldAdd(e){
      let {filters} = this.formData
      const {newIndex} = e
      if(e.to?.id === 'filters'){
        let filter = filters[newIndex]
        let filterObj = {
            uuid: filter.uuid,
            alia: filter.alia,
            dataType: filter.dataType,
            field: filter.field,
            filterType: FilterType.INCLUDE,
            dateRange: DateRange.TODAY,
            spliceType: this.spliceType,
            values: []
          }
        if(filter.dataType === DataType.TEXT){
          filterObj.filterType = FilterType.INCLUDE
        } else if (filter.dataType === DataType.NUMBER) {
          filterObj.filterType = FilterType.EQUAL
        } else if (filter.dataType === DataType.DATE) {
          filterObj.filterType = FilterType.DATE_YES
        } else {
          this.$message.warning('该字段不能作为过滤条件')
          this.formData.filters = this.formData.filters.splice(newIndex, 1)
          return
        }
        
        filters[newIndex] = filterObj
        this.oneFilterData = filterObj
        this.filterModalVisible = true
      }
    },
    filterClose(){
      this.filterModalVisible = false
      this.formData.filters = this.formData.filters.filter(function(v,i,ar) {
          return i!==ar.length-1;
      });
    },
    colorConfigSave(data){
      this.formData.colorConfig = data
      this.colorConfigModalVisible = false
    },
    filterSave(data){
      this.filterModalVisible = false
      const {uuid} = this.oneFilterData
      let filter = this.formData.filters.find(d => d.uuid === uuid)
      filter = Object.assign(filter, data)
      this.updateWorksheetData()
    },
    async formListSave(id){
      this.formData.worksheetId = id
      let detail = await getWorksheetDetail(id)
      
      let worksheetData = await getFilterDataList({
        worksheetId: id,
        format: 1
      })
      this.fieldList = detail?.fields.map(d => {
        let obj = {
          alia: d.alia,
          dataType: d.dataType,
          field: d.name,
          rename: d.alia,
          computeType: d.dataType !== DataType.NUMBER ? 'count': 'sum'
        }

        if(d.dataType === DataType.DATE){
          obj.includeTime = d.options.valueFormat.includes('H')
          obj.groupType = 'day'
        }
        return obj
      }) || []
      this.worksheetData = worksheetData.data
      this.formData.xAxis = []
      this.formData.yAxis = []
      this.formData.filters = []
      this.worksheetName = detail?.name || ""
      this.formListVisible = false
    },
    handleNameChange(v){
      this.formNameStyle = `width: ${getStrPx(v.target.value, 16) + 5}px`
    },
    async updateWorksheetData() {
      const {worksheetId, sortField, filters, isAsc} = this.formData
      let filterData = {
        worksheetId,
        sortField,
        filters,
        isAsc,
        format: 1
      }
      let data = await getFilterDataList(filterData)
      this.worksheetData = data?.data || []
    },
    close() {
      this.$emit("close", this.type);
    },
    save(params) {
      this.$emit('save', this.type, this.$props.model, params)
    },
    handleAddColorLimit(){
      this.formData.colorLimit.push({
        uuid: this.createId(),
        field: '',
        colorValue: "#ff0000",
        limitType: 'greater',
        limitValue: 0,
        front: 0,
        later: 1
      })
    },
    handleDeleteColorLimit(uuid){
      this.formData.colorLimit = this.formData.colorLimit.filter(c => c.uuid !== uuid)
    },
    handleSpliceChange(type){
      this.formData.filters = this.formData.filters.map(c => {
        c.spliceType = type
        return c
      })
      this.updateWorksheetData()
    },
    createId(){
        return Number(Math.random().toString().substr(3,length) + Date.now()).toString(36);
    },
    handleSave(){
      this.save(this.formData)
      this.close()
    }
  },
  computed:{
    appId() {
        return this.$route.params.appId;
    },
    numberFields(){
      return this.fieldList.filter(f => f.dataType === DataType.NUMBER)
    },
    notNumberFields(){
      return this.fieldList.filter(f => f.dataType !== DataType.NUMBER)
    },
  },
  async mounted(){
      this.formData.worksheetId = this.worksheetId
      let detail = await getWorksheetDetail(this.worksheetId)
      this.fieldList = detail?.fields.map(d => {
        let obj = {
          alia: d.alia,
          dataType: d.dataType,
          field: d.name,
          rename: d.alia,
          computeType: d.dataType !== DataType.NUMBER ? 'count': 'sum'
        }
        if(d.dataType === DataType.DATE){
          obj.includeTime = d.options.valueFormat.includes('H')
          obj.groupType = 'day'
        }
        return obj
      }) || []
      this.worksheetName = detail?.name || ""

      let worksheetData
      if(this.model === 'create'){
        worksheetData = await getFilterDataList({
          worksheetId: this.worksheetId,
          format: 1
        })
      }else if(this.model === 'update'){
        let {xAxis, yAxis} = this.config
        const {worksheetId, sortField, filters, isAsc} = this.config
        let filterData = {
          worksheetId,
          sortField,
          filters,
          isAsc,
          format: 1
        }
        worksheetData = await getFilterDataList(filterData)
        if(!Array.isArray(xAxis)){
          let newXAxis = [{
            uuid: this.createId(),
            dataType: DataType.TEXT,
            alia: xAxis,
            rename: xAxis,
            computeType: 'count'
          }]

          let newYAxis = yAxis.map(y => (Object.assign(y, {rename: y.alia, dataType: DataType.NUMBER})))
          this.formData = Object.assign(this.config, {
            xAxis: newXAxis,
            yAxis: newYAxis,
          })
        }else {
          this.formData = this.config
        }
        if(this.config.filters.length > 0){
          this.spliceType = this.config.filters[0].spliceType
        }
      }
      
      this.worksheetData = worksheetData?.data || []
      this.formNameStyle = `width: ${getStrPx(this.formData.name, 16) + 5}px`
  },
};
</script>
<style>

</style>
<style lang="less">
.chart-setting-config{
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  width: 100%;
  height: 100%;
  background-color: #fff;

  .title{
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 16px;    
    -webkit-box-shadow: 0 2px 5px 0 hsl(0deg 0% 39% / 15%);
    box-shadow: 0 2px 5px 0 hsl(0deg 0% 39% / 15%);
    height: 60px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0 30px;
    cursor: default;
    border-bottom: 1px solid #D9D9D9;

    .title-left{
      flex: 1;
      display: flex;
      align-items: center;
      
      i {
        color: rgb(127, 178, 255);
        // color: #0db3a6;
        font-size: 30px;
        font-weight: 900;
        cursor: pointer;
      }

      input {
        max-width: 100%;
        position: relative;
        margin-left: 20px;
        height: 30px;
        font-size: 16px;
        color: #1F2D3D !important;
        outline: 0;
        border: none;
        box-shadow: none;
        background: 0 0;
        border-bottom: dashed 1px #bababa;
        -webkit-border-radius: 0;
        -moz-border-radius: 0;
        border-radius: 0;
      }
    }

    .title-right{
      width: 200px;
      display: flex;
      justify-content: right;
    }
  }
  
  .chart-config {
    position: absolute;
    top: 60px;
    left: 0;
    right: 0;
    bottom: 0;
    background: #F4F6F9;
    color: black;

    .chart-left {
      width: 250px;
      height: 100%;
      border-right: 1px solid #D9D9D9;

      .data-block{
        height: 100px;
        // margin-bottom: 10px;


        .block-data-source{
          border-bottom: 1px solid #e9e9e9;
          padding: 10px 10px 20px 20px;
          font-size: 12px;

          i{
            color: rgb(127, 178, 255);
            margin-right: 10px;
          }
        }
      }
      
      .block-head{
        display: flex;
        justify-content: space-between;
        font-size: 14px;
        // font-weight: bold;
        padding: 10px 20px;

        .block-title{
        }

        .block-right{
          color: rgb(127, 178, 255);
          font-size: 14px;
          // color: #0db3a6;
          cursor: pointer;
        }
      }

      .fields-block{
        margin-bottom: 20px;
        position: relative;
        height: 100%;

        .block-content{
          overflow: auto;   
          position: absolute;
          overflow: auto;
          bottom: 0;
          top: 44px;
          width: 100%;
          
          .item {
            // height: 30px;
            height: 25px;
            padding: 0 20px;
            display: flex;
            align-items: center;
            cursor: move;
            font-size: 12px;

            span {
              margin-left: 10px;
            }

            i{
              color: rgb(127, 178, 255);
            }
          }
          .item:hover, .active {
            background-color: #dae3eb;
          }
        }
      }
    }
    .chart-middle {
      position: absolute;
      top: 0;
      left: 250px;
      right: 300px;
      min-width: 650px;
      padding: 10px 15px;
      display: flex;
      flex-direction: column;
      height: 100%;

      .chart-axis {
        position: relative;
        width: 100%;
        background: white;
        margin-bottom: 10px;
        padding: 0 10px;
        border-radius: 3px;
        border: 1px dashed #D9D9D9;

        .axis-head{
          width: 60px;
          position: absolute;
          line-height: 35px;
        }

        .drag-target{
          min-height: 35px;
          max-height: 90px;
          padding: 2.5px 10px 2.5px 70px;
          line-height: 30px;

          .drag-tip{
            font-size: 12px;
            color: #91A1B7;
            display: block;
            position: absolute;
          }

          .drag-axis{
            display: flex;
            width: 100%;
            min-height: 35px;
            flex-wrap: wrap;
            align-items: center;
            overflow-y: auto;
          }
        }

        .axis-split-type {
          position: absolute;
          right: 5px;
          top: 5px;

          .ant-select-selection{
            border: none
          }
        }
      }

      .chart-content{
        flex: 1;
        background: white;
      }

    }
    .chart-right {
      position: absolute;
      top: 0;
      right: 0;
      width: 300px;
      height: 100%;
      overflow: auto;
      border-left: 1px solid #D9D9D9;

      .config-block{
        margin-bottom: 10px;
        input{
          color: black !important;
        }

        .block-head{
          padding: 10px 10px 20px 20px;
          font-size: 14px;
        }

        .color-limit-container{
          margin: 2px 20px;
        }

        .config-chart-type{
          padding: 10px 10px 20px 20px;

          .ant-radio-button-wrapper{
            color: #0db3a6;
            width: 50px;
            font-size: 20px;
            line-height: 50px;
            margin-left: 5px;
            height: 50px;
            background: transparent;
            border: none;
            padding: 0 12px;
          }
          .ant-radio-button-wrapper:hover {
            color: #0db3a6;
            background: white;
          }

          .ant-radio-button-wrapper-checked{
            background-color: white;
            border: #0db3a6 2px solid;
          }

          .ant-radio-button-wrapper:not(:first-child)::before{
            background-color: transparent;
          }
        }

        .config-color {
          padding: 0 20px;
          font-size: 14px;
        }

        .config-sort{
          padding: 0 60px 0 20px;
          display: flex;
          justify-content: space-between;
          align-items: center;

          
          .ant-select-selection{
              border: 1px solid #d9d9d9 !important;
              background-color: #fff !important;
          }
        }
        .config-font {
          padding: 0 60px 0 20px;
          font-size: 14px;
          display: flex;
          justify-content: space-between;
          align-items: center;

          input {
            border: 1px solid #bababa !important;
            text-align: center;
          }
        }
        .length-button{
          width: 220px;
          margin-left: 20px;
        }
      }
    }

  }
}
</style>